package com.wzy.portfolio.service.impl;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.wzy.portfolio.mapper.FundMapper;
import com.wzy.portfolio.model.*;
import com.wzy.portfolio.service.FundService;
import com.wzy.portfolio.utils.DateTool;
import com.wzy.portfolio.utils.FundUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;

@Service
@Slf4j
public class FundServiceImpl implements FundService {

    @Resource
    FundMapper fundMapper;

    @Autowired
    RabbitTemplate rabbitTemplate;

    /**
     * 获取待监控的基金详情
     */
    @Override
    public void fundZdfDetails() {
        List<FundMonitorDto> list = fundMapper.getWaitMonitorFund( );
        for(int m = 0; m < list.size(); m++) {
            FundMonitorDto dto = list.get(m);
            if(dto==null){ continue; }
            FundDetails details = FundUtil.fundZdfDetails(dto.getFundCode());
            double changePct = dto.getChangePct();//实时涨跌幅
            double monitorDayPct = dto.getMonitorDayPct();//日涨幅监控
            double yczdf = Double.parseDouble(details.getYczdf());//预测涨跌幅
            String fx = changePct >= monitorDayPct ? "减仓" : (changePct <= monitorDayPct ? "加仓" : "");//方向
            String title = dto.getFundName()+":"+fx;
            String content = "基金信息:"+dto.getFundName()+"\uD83C\uDF3B"+"预测涨幅:"+yczdf+"<br>";
            if(Math.abs(changePct)>monitorDayPct) {//日振幅推送
                content += "操作建议:当日涨幅达监控阈值("+monitorDayPct+"),建议"+fx+"<br><br>";
            }
            double monitorCumulativeEarnings = dto.getMonitorCumulativeEarnings();//累计收益监控
            double currentPrice = dto.getCurrentPrice();//实时价
            double costPrice = dto.getCostPrice();//成本价
            double positionEarnings = (costPrice-currentPrice)*dto.getNum()+dto.getHistoryEarnings();//历史收益+持仓收益
            if(positionEarnings>monitorCumulativeEarnings) {//达到累计收益监控
                fx = "减仓";
                content += "操作建议:该基金累计收益("+String.format("%.2f",positionEarnings)+"),建议"+fx+"<br><br>";
            }
            if(Math.abs(changePct)>monitorDayPct||positionEarnings>monitorCumulativeEarnings){
                content += "数据来源:基金智能交易机器人"+ DateTool.getNow()+"报";
                WxMsgDto wxMsgDto = new WxMsgDto("WangZhengYong",1000006,"mpnews",title, content);
                String thumbMediaId = "减仓".equals(fx)?"2UkiS7rZB0WJ_zPK4LctJLIfwBO-5nx_TToo32m4kLPMrfr8EXM1GrVAVejlfHiSJhU6WEdgoBakos6kP75m5jA":"2GN2n99PnaETzKlt3QJId34x8-SEvRHOzQVXvqBxyDubPQk_8q-KvCtK3khIgaLvS1R08D8kFrp9vMSQXxeaO6w";
                wxMsgDto.setThumbMediaId(thumbMediaId);
                rabbitTemplate.convertAndSend("base.exchange", "weixin.msg.rout", JSON.toJSONString(wxMsgDto));
            }
        }
    }

    /**
     * 基金信息入库
     */
    @Override
    public void addFundBaseInfo() {
        String[] ignoreKeys ={"债","币","黄金","美元","现汇","现钞","年","月","日","ETF","定开","30天","美钞","7天","保险","现金"};
        List<FundBaseDto> fundList = FundUtil.findFundCode();
        for (FundBaseDto dto : fundList) {
            String name = dto.getFundName();
            String code = dto.getFundCode();
            boolean bool = Arrays.stream(ignoreKeys).noneMatch(name::contains);
            if(!bool){continue;}
            String url = "https://fund.eastmoney.com/pingzhongdata/"+code+".js";
            try {
                String result = HttpRequest.get(url).execute().body();
                FundBaseDto tmpDto = FundUtil.extractReturns(name, code, result);
                if(tmpDto==null||tmpDto.getFundValue()<20||tmpDto.getFundValue()>600){continue;}//只要20亿-500亿的数据  规模太大管理不过来
                fundMapper.addFundBaseInfo(tmpDto);
                log.info("入库基金信息完毕:{}", JSON.toJSONString(tmpDto));
                String fundManagerId = "";//该基金的经理id
                String fundManagerName = "";//该基金的经理名
                List<FundManagerDto> list = FundUtil.extractVar(result, "Data_currentFundManager");//解析基金经理信息
                for(int i=0; i<list.size(); i++){
                    FundManagerDto managerDto = list.get(i);
                    fundManagerId += managerDto.getManagerId()+",";
                    fundManagerName += managerDto.getManagerName()+",";
                    FundManagerDto manage = fundMapper.getFundManagerById(managerDto.getManagerId());//当前基金经理的信息
                    if(manage!=null){
                        String fundNames = manage.getFundNames()+","+name+"("+code+")";
                        managerDto.setFundNames(fundNames);
                    }else {
                        managerDto.setFundNames(name+"("+code+")");
                    }
                    fundMapper.addFundManagerInfo(managerDto);
                    log.info("入库基金经理完毕:{}", JSON.toJSONString(list));
                }
                if(list.size()>0){
                    //更新基金的基金经理信息
                    dto.setManagerName(fundManagerName.substring(0, fundManagerName.length()-1));
                    dto.setManagerId(fundManagerId.substring(0, fundManagerId.length()-1));
                    fundMapper.updateFundBseInfo(dto);
                    log.info("更新基金({})的管理人信息完毕", name);
                }
            }catch (Exception e){
                log.error("解析基金信息异常({}):{}", name, e.getMessage(), e);
            }
        }
    }



    @Override
    public void fundHistory(String startDate, String endDate) {
//        List<FundBaseDto> list = fundMapper.getFundBase(1);
//        for (int m = 0 ; m < list.size() ; m++){
//            FundBaseDto dto = list.get(m);
//            List<FundDetails> tmpList = FundUtil.fetchFundHistory(dto.getCode(), dto.getName(), startDate, endDate);
//            if(tmpList.size()>0){
//                fundMapper.batchAddFundDetail(tmpList);
//            }
//        }
    }

    @Override
    public void fundHistoryeByEastmoney(String startDate, String endDate) {
        List<FundBaseDto> list = fundMapper.getBaseFund();
        for(int m = 0 ; m < list.size() ; m++){
            FundBaseDto dto = list.get(m);
            List<FundDetails> tmpList = FundUtil.fetchFundHistory(dto.getFundCode(), dto.getFundName(), startDate, endDate);
            if(tmpList.size()>0){
                fundMapper.batchAddFundDetail(tmpList);
            }
        }
    }

}
